﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Razor.Parser.TokenizerBackedParser`3
// Assembly: System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: 682513D6-F37E-48AC-9909-F3EE103CFF14
// Assembly location: D:\Project\Idea\无人机外网\uav\客户端工程\排查工具\bin\Release\System.Web.Razor.dll

using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Web.Razor.Editor;
using System.Web.Razor.Generator;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer;
using System.Web.Razor.Tokenizer.Symbols;
using System.Web.Razor.Utils;

namespace System.Web.Razor.Parser
{
  /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Represents a tokenizer backed parser.</summary>
  /// <typeparam name="TTokenizer">The type of tokenizer.</typeparam>
  /// <typeparam name="TSymbol">The type of symbol.</typeparam>
  /// <typeparam name="TSymbolType">The type of SymbolType.</typeparam>
  public abstract class TokenizerBackedParser<TTokenizer, TSymbol, TSymbolType> : ParserBase
    where TTokenizer : System.Web.Razor.Tokenizer.Tokenizer<TSymbol, TSymbolType>
    where TSymbol : SymbolBase<TSymbolType>
  {
    private TokenizerView<TTokenizer, TSymbol, TSymbolType> _tokenizer;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a new instance of the <see cref="T:System.Web.Razor.Parser.TokenizerBackedParser`3" /> class.</summary>
    protected TokenizerBackedParser() => this.Span = new SpanBuilder();

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets the <see cref="T:System.Web.Razor.Parser.SyntaxTree.SpanBuilder" /> associated with this instance.</summary>
    /// <returns>The <see cref="T:System.Web.Razor.Parser.SyntaxTree.SpanBuilder" /> associated with this instance.</returns>
    protected SpanBuilder Span { get; set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the tokenizer.</summary>
    /// <returns>The tokenizer.</returns>
    protected TokenizerView<TTokenizer, TSymbol, TSymbolType> Tokenizer => this._tokenizer ?? this.InitTokenizer();

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets the span configuration.</summary>
    /// <returns>The span configuration.</returns>
    protected Action<SpanBuilder> SpanConfig { get; set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the current symbol of this instance.</summary>
    /// <returns>The current symbol of this instance.</returns>
    protected TSymbol CurrentSymbol => this.Tokenizer.Current;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code..Gets the previous symbol of this instance.</summary>
    protected TSymbol PreviousSymbol { get; private set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the current location of the current instance.</summary>
    /// <returns>The current location of the current instance.</returns>
    protected SourceLocation CurrentLocation => !this.EndOfFile && (object) this.CurrentSymbol != null ? this.CurrentSymbol.Start : this.Context.Source.Location;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets a value indicating whether the tokenizer is in the end of file.</summary>
    /// <returns>true if the tokenizer is in the end of file; otherwise, false.</returns>
    protected bool EndOfFile => this.Tokenizer.EndOfFile;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the language used for parsing.</summary>
    /// <returns>The language used for parsing.</returns>
    protected abstract LanguageCharacteristics<TTokenizer, TSymbol, TSymbolType> Language { get; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Handles the embedded transition.</summary>
    protected virtual void HandleEmbeddedTransition()
    {
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether this instance is at embedded transition.</summary>
    /// <returns>true if this instance is at embedded transition; otherwise, false.</returns>
    /// <param name="allowTemplatesAndComments">true to allow templates and comments; otherwise, false.</param>
    /// <param name="allowTransitions">true to allow transitions; otherwise, false.</param>
    protected virtual bool IsAtEmbeddedTransition(
      bool allowTemplatesAndComments,
      bool allowTransitions)
    {
      return false;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Builds a specified span.</summary>
    /// <param name="span">The span to build.</param>
    /// <param name="start">The start location to build the span.</param>
    /// <param name="content">The content of the span.</param>
    public override void BuildSpan(SpanBuilder span, SourceLocation start, string content)
    {
      foreach (TSymbol symbol1 in this.Language.TokenizeString(start, content))
      {
        ISymbol symbol2 = (ISymbol) symbol1;
        span.Accept(symbol2);
      }
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Initializes a specified span.</summary>
    /// <param name="span">The span to initialize.</param>
    protected void Initialize(SpanBuilder span)
    {
      if (this.SpanConfig == null)
        return;
      this.SpanConfig(span);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the parser advances to the next token.</summary>
    /// <returns>true if the parser advances to the next token; otherwise, false.</returns>
    protected internal bool NextToken()
    {
      this.PreviousSymbol = this.CurrentSymbol;
      return this.Tokenizer.Next();
    }

    private TokenizerView<TTokenizer, TSymbol, TSymbolType> InitTokenizer() => this._tokenizer = new TokenizerView<TTokenizer, TSymbol, TSymbolType>(this.Language.CreateTokenizer((ITextDocument) this.Context.Source));

    [Conditional("DEBUG")]
    internal void Assert(TSymbolType expectedType)
    {
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Puts the transition back.</summary>
    /// <param name="symbol">The symbol.</param>
    protected internal void PutBack(TSymbol symbol)
    {
      if ((object) symbol == null)
        return;
      this.Tokenizer.PutBack(symbol);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Puts the transition back.</summary>
    /// <param name="symbols">The symbols.</param>
    protected internal void PutBack(IEnumerable<TSymbol> symbols)
    {
      foreach (TSymbol symbol in symbols.Reverse<TSymbol>())
        this.PutBack(symbol);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Puts the current transition back.</summary>
    protected internal void PutCurrentBack()
    {
      if (this.EndOfFile || (object) this.CurrentSymbol == null)
        return;
      this.PutBack(this.CurrentSymbol);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the parsing is balance.</summary>
    /// <returns>true if the parsing is balance; otherwise, false.</returns>
    /// <param name="mode">The balancing mode.</param>
    protected internal bool Balance(BalancingModes mode)
    {
      TSymbolType type = this.CurrentSymbol.Type;
      TSymbolType symbolType = this.Language.FlipBracket(type);
      SourceLocation currentLocation = this.CurrentLocation;
      this.AcceptAndMoveNext();
      if (this.EndOfFile && !mode.HasFlag((Enum) BalancingModes.NoErrorOnFailure))
        this.Context.OnError(currentLocation, RazorResources.ParseError_Expected_CloseBracket_Before_EOF, (object) this.Language.GetSample(type), (object) this.Language.GetSample(symbolType));
      return this.Balance(mode, type, symbolType, currentLocation);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the parsing is balance.</summary>
    /// <returns>true if the parsing is balance; otherwise, false.</returns>
    /// <param name="mode">The balancing mode.</param>
    /// <param name="left">The left parse.</param>
    /// <param name="right">The right parse.</param>
    /// <param name="start">The start of the mode.</param>
    protected internal bool Balance(
      BalancingModes mode,
      TSymbolType left,
      TSymbolType right,
      SourceLocation start)
    {
      int absoluteIndex = this.CurrentLocation.AbsoluteIndex;
      int num = 1;
      if (!this.EndOfFile)
      {
        IList<TSymbol> symbolList = (IList<TSymbol>) new List<TSymbol>();
        do
        {
          if (this.IsAtEmbeddedTransition(mode.HasFlag((Enum) BalancingModes.AllowCommentsAndTemplates), mode.HasFlag((Enum) BalancingModes.AllowEmbeddedTransitions)))
          {
            this.Accept((IEnumerable<TSymbol>) symbolList);
            symbolList.Clear();
            this.HandleEmbeddedTransition();
            absoluteIndex = this.CurrentLocation.AbsoluteIndex;
          }
          if (this.At(left))
            ++num;
          else if (this.At(right))
            --num;
          if (num > 0)
            symbolList.Add(this.CurrentSymbol);
        }
        while (num > 0 && this.NextToken());
        if (num > 0)
        {
          if (!mode.HasFlag((Enum) BalancingModes.NoErrorOnFailure))
            this.Context.OnError(start, RazorResources.ParseError_Expected_CloseBracket_Before_EOF, (object) this.Language.GetSample(left), (object) this.Language.GetSample(right));
          if (mode.HasFlag((Enum) BalancingModes.BacktrackOnFailure))
          {
            this.Context.Source.Position = absoluteIndex;
            this.NextToken();
          }
          else
            this.Accept((IEnumerable<TSymbol>) symbolList);
        }
        else
          this.Accept((IEnumerable<TSymbol>) symbolList);
      }
      return num == 0;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the token with the given type would pass.</summary>
    /// <returns>true if the token with the give type would pass; otherwise, false.</returns>
    /// <param name="type">The type of the token.</param>
    protected internal bool NextIs(TSymbolType type) => this.NextIs((Func<TSymbol, bool>) (sym => (object) sym != null && object.Equals((object) type, (object) sym.Type)));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the token with the given types would pass.</summary>
    /// <returns>true if the token with the given types would pass; otherwise, false.</returns>
    /// <param name="types">The types.</param>
    protected internal bool NextIs(params TSymbolType[] types) => this.NextIs((Func<TSymbol, bool>) (sym => (object) sym != null && ((IEnumerable<TSymbolType>) types).Any<TSymbolType>((Func<TSymbolType, bool>) (t => object.Equals((object) t, (object) sym.Type)))));

    /// <summary>Determines whether the token with the given condition would pass.</summary>
    /// <returns>true if the token with the given condition would pass; otherwise, false.</returns>
    /// <param name="condition">The condition.</param>
    protected internal bool NextIs(Func<TSymbol, bool> condition)
    {
      TSymbol currentSymbol = this.CurrentSymbol;
      this.NextToken();
      int num = condition(this.CurrentSymbol) ? 1 : 0;
      this.PutCurrentBack();
      this.PutBack(currentSymbol);
      this.EnsureCurrent();
      return num != 0;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the token with the given type was parsed.</summary>
    /// <returns>true if the token with the given type was parsed; otherwise, false.</returns>
    /// <param name="type">The type of the token.</param>
    protected internal bool Was(TSymbolType type) => (object) this.PreviousSymbol != null && object.Equals((object) this.PreviousSymbol.Type, (object) type);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the token is at the specified type.</summary>
    /// <returns>true if the token is at the specified type; otherwise, false.</returns>
    /// <param name="type">The type.</param>
    protected internal bool At(TSymbolType type) => !this.EndOfFile && (object) this.CurrentSymbol != null && object.Equals((object) this.CurrentSymbol.Type, (object) type);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the parser accepts and moves to the next tokenizer.</summary>
    /// <returns>true if the parser accepts and moves to the next tokenizer; otherwise, false.</returns>
    protected internal bool AcceptAndMoveNext()
    {
      this.Accept(this.CurrentSymbol);
      return this.NextToken();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the parser accepts single whitespace character.</summary>
    /// <returns>true if the parser accepts single whitespace character; otherwise, false.</returns>
    protected TSymbol AcceptSingleWhiteSpaceCharacter()
    {
      if (!this.Language.IsWhiteSpace(this.CurrentSymbol))
        return default (TSymbol);
      Tuple<TSymbol, TSymbol> tuple = this.Language.SplitSymbol(this.CurrentSymbol, 1, this.Language.GetKnownSymbolType(KnownSymbolType.WhiteSpace));
      this.Accept(tuple.Item1);
      this.Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
      this.NextToken();
      return tuple.Item2;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts the list of symbols</summary>
    /// <param name="symbols">The list of symbols.</param>
    protected internal void Accept(IEnumerable<TSymbol> symbols)
    {
      foreach (TSymbol symbol in symbols)
        this.Accept(symbol);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts the specified symbol.</summary>
    /// <param name="symbol">The symbol to accept.</param>
    protected internal void Accept(TSymbol symbol)
    {
      if ((object) symbol == null)
        return;
      foreach (RazorError error in symbol.Errors)
        this.Context.Errors.Add(error);
      this.Span.Accept((ISymbol) symbol);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the parser accepts all types of tokenizer.</summary>
    /// <returns>true of the parser accepts all types of tokenizer; otherwise, false.</returns>
    /// <param name="types">The types.</param>
    protected internal bool AcceptAll(params TSymbolType[] types)
    {
      foreach (TSymbolType type in types)
      {
        if ((object) this.CurrentSymbol == null || !object.Equals((object) this.CurrentSymbol.Type, (object) type))
          return false;
        this.AcceptAndMoveNext();
      }
      return true;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Adds a marker symbol if necessary.</summary>
    protected internal void AddMarkerSymbolIfNecessary() => this.AddMarkerSymbolIfNecessary(this.CurrentLocation);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Adds a marker symbol if necessary.</summary>
    /// <param name="location">The location where to add the symbol.</param>
    protected internal void AddMarkerSymbolIfNecessary(SourceLocation location)
    {
      if (this.Span.Symbols.Count != 0 || this.Context.LastAcceptedCharacters == AcceptedCharacters.Any)
        return;
      this.Accept(this.Language.CreateMarkerSymbol(location));
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Outputs a token with span kind.</summary>
    /// <param name="kind">The span kind.</param>
    protected internal void Output(SpanKind kind)
    {
      this.Configure(new SpanKind?(kind), new AcceptedCharacters?());
      this.Output();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Outputs a token with a given span kind and accepted characters.</summary>
    /// <param name="kind">The span kind.</param>
    /// <param name="accepts">The accepted characters.</param>
    protected internal void Output(SpanKind kind, AcceptedCharacters accepts)
    {
      this.Configure(new SpanKind?(kind), new AcceptedCharacters?(accepts));
      this.Output();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Outputs a token with accepted characters.</summary>
    /// <param name="accepts">The accepted characters.</param>
    protected internal void Output(AcceptedCharacters accepts)
    {
      this.Configure(new SpanKind?(), new AcceptedCharacters?(accepts));
      this.Output();
    }

    private void Output()
    {
      if (this.Span.Symbols.Count <= 0)
        return;
      this.Context.AddSpan(this.Span.Build());
      this.Initialize(this.Span);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Pushes the span configuration.</summary>
    /// <returns>An <see cref="T:System.IDisposable" /> that shuts down the configuration.</returns>
    protected IDisposable PushSpanConfig() => this.PushSpanConfig((Action<SpanBuilder, Action<SpanBuilder>>) null);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Pushes the span configuration.</summary>
    /// <returns>An <see cref="T:System.IDisposable" /> that shuts down the configuration.</returns>
    /// <param name="newConfig">The new configuration.</param>
    protected IDisposable PushSpanConfig(Action<SpanBuilder> newConfig) => this.PushSpanConfig(newConfig == null ? (Action<SpanBuilder, Action<SpanBuilder>>) null : (Action<SpanBuilder, Action<SpanBuilder>>) ((span, _) => newConfig(span)));

    /// <summary>Pushes the span configuration.</summary>
    /// <returns>An <see cref="T:System.IDisposable" /> that shuts down the configuration.</returns>
    /// <param name="newConfig">The new configuration.</param>
    protected IDisposable PushSpanConfig(
      Action<SpanBuilder, Action<SpanBuilder>> newConfig)
    {
      Action<SpanBuilder> old = this.SpanConfig;
      this.ConfigureSpan(newConfig);
      return (IDisposable) new DisposableAction((Action) (() => this.SpanConfig = old));
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Configures the span.</summary>
    /// <param name="config">The configuration.</param>
    protected void ConfigureSpan(Action<SpanBuilder> config)
    {
      this.SpanConfig = config;
      this.Initialize(this.Span);
    }

    /// <summary>Configures the span.</summary>
    /// <param name="config">The configuration.</param>
    protected void ConfigureSpan(Action<SpanBuilder, Action<SpanBuilder>> config)
    {
      Action<SpanBuilder> prev = this.SpanConfig;
      this.SpanConfig = config != null ? (Action<SpanBuilder>) (span => config(span, prev)) : (Action<SpanBuilder>) null;
      this.Initialize(this.Span);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates the expected token with the given type.</summary>
    /// <param name="type">The type.</param>
    protected internal void Expected(KnownSymbolType type) => this.Expected(this.Language.GetKnownSymbolType(type));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Indicates the expected token with the given types.</summary>
    /// <param name="types">The types.</param>
    protected internal void Expected(params TSymbolType[] types) => this.AcceptAndMoveNext();

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether parsing a token with the given type is optional.</summary>
    /// <returns>true if parsing a token with the given type is optional; otherwise, false.</returns>
    /// <param name="type">The type of the token.</param>
    protected internal bool Optional(KnownSymbolType type) => this.Optional(this.Language.GetKnownSymbolType(type));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether parsing a token with the given type is optional.</summary>
    /// <returns>true if parsing a token with the given type is optional; otherwise, false.</returns>
    /// <param name="type">The type of the token.</param>
    protected internal bool Optional(TSymbolType type)
    {
      if (!this.At(type))
        return false;
      this.AcceptAndMoveNext();
      return true;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the expected token is required.</summary>
    /// <returns>true if the expected token is required; otherwise, false.</returns>
    /// <param name="expected">The expected token.</param>
    /// <param name="errorIfNotFound">true to display an error if not found; otherwise, false.</param>
    /// <param name="errorBase">The error base.</param>
    protected internal bool Required(TSymbolType expected, bool errorIfNotFound, string errorBase)
    {
      bool flag = this.At(expected);
      if (!flag & errorIfNotFound)
      {
        string str;
        if (this.Language.IsNewLine(this.CurrentSymbol))
          str = RazorResources.ErrorComponent_Newline;
        else if (this.Language.IsWhiteSpace(this.CurrentSymbol))
          str = RazorResources.ErrorComponent_Whitespace;
        else if (this.EndOfFile)
          str = RazorResources.ErrorComponent_EndOfFile;
        else
          str = string.Format((IFormatProvider) CultureInfo.CurrentCulture, RazorResources.ErrorComponent_Character, (object) this.CurrentSymbol.Content);
        this.Context.OnError(this.CurrentLocation, errorBase, (object) str);
      }
      return flag;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether to ensure the current parser.</summary>
    /// <returns>true if to ensure the current parser; otherwise, false.</returns>
    protected bool EnsureCurrent() => (object) this.CurrentSymbol != null || this.NextToken();

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts the token while a token of the given type is not found.</summary>
    /// <param name="type">The type of the token.</param>
    protected internal void AcceptWhile(TSymbolType type) => this.AcceptWhile((Func<TSymbol, bool>) (sym => object.Equals((object) type, (object) sym.Type)));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts token while the token of the given type has been reached.</summary>
    /// <param name="type1">The type of the first token.</param>
    /// <param name="type2">The type of the second token.</param>
    protected internal void AcceptWhile(TSymbolType type1, TSymbolType type2) => this.AcceptWhile((Func<TSymbol, bool>) (sym => object.Equals((object) type1, (object) sym.Type) || object.Equals((object) type2, (object) sym.Type)));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts token while the token of the given type has been reached.</summary>
    /// <param name="type1">The type of the first token.</param>
    /// <param name="type2">The type of the second token.</param>
    /// <param name="type3">The type of the third token.</param>
    protected internal void AcceptWhile(TSymbolType type1, TSymbolType type2, TSymbolType type3) => this.AcceptWhile((Func<TSymbol, bool>) (sym => object.Equals((object) type1, (object) sym.Type) || object.Equals((object) type2, (object) sym.Type) || object.Equals((object) type3, (object) sym.Type)));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts token while the token of the given types has been reached.</summary>
    /// <param name="types">The types.</param>
    protected internal void AcceptWhile(params TSymbolType[] types) => this.AcceptWhile((Func<TSymbol, bool>) (sym => ((IEnumerable<TSymbolType>) types).Any<TSymbolType>((Func<TSymbolType, bool>) (expected => object.Equals((object) expected, (object) sym.Type)))));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts token until a token of the given type is found.</summary>
    /// <param name="type">The type of the token.</param>
    protected internal void AcceptUntil(TSymbolType type) => this.AcceptWhile((Func<TSymbol, bool>) (sym => !object.Equals((object) type, (object) sym.Type)));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts token until a token of the given type is found and it will backup so that the next token is of the given type.</summary>
    /// <param name="type1">The type of the first token.</param>
    /// <param name="type2">The type of the second token.</param>
    protected internal void AcceptUntil(TSymbolType type1, TSymbolType type2) => this.AcceptWhile((Func<TSymbol, bool>) (sym => !object.Equals((object) type1, (object) sym.Type) && !object.Equals((object) type2, (object) sym.Type)));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts the given tokens until a token of the given type is found.</summary>
    /// <param name="type1">The type of the first token.</param>
    /// <param name="type2">The type of the second token.</param>
    /// <param name="type3">The type of the third token.</param>
    protected internal void AcceptUntil(TSymbolType type1, TSymbolType type2, TSymbolType type3) => this.AcceptWhile((Func<TSymbol, bool>) (sym => !object.Equals((object) type1, (object) sym.Type) && !object.Equals((object) type2, (object) sym.Type) && !object.Equals((object) type3, (object) sym.Type)));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Accepts token until a token of the given types is found.</summary>
    /// <param name="types">The types of the token.</param>
    protected internal void AcceptUntil(params TSymbolType[] types) => this.AcceptWhile((Func<TSymbol, bool>) (sym => ((IEnumerable<TSymbolType>) types).All<TSymbolType>((Func<TSymbolType, bool>) (expected => !object.Equals((object) expected, (object) sym.Type)))));

    /// <summary>Accepts token while the condition has been reached.</summary>
    /// <param name="condition">The condition.</param>
    protected internal void AcceptWhile(Func<TSymbol, bool> condition) => this.Accept(this.ReadWhileLazy(condition));

    /// <summary>Reads a token while the condition is not reached.</summary>
    /// <returns>The token to read.</returns>
    /// <param name="condition">The condition.</param>
    protected internal IEnumerable<TSymbol> ReadWhile(Func<TSymbol, bool> condition) => (IEnumerable<TSymbol>) this.ReadWhileLazy(condition).ToList<TSymbol>();

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the parser accepts whitespace in lines.</summary>
    /// <returns>true if the parser accepts whitespace in lines; otherwise, false.</returns>
    protected TSymbol AcceptWhiteSpaceInLines()
    {
      TSymbol symbol = default (TSymbol);
      while (this.Language.IsWhiteSpace(this.CurrentSymbol) || this.Language.IsNewLine(this.CurrentSymbol))
      {
        if ((object) symbol != null)
          this.Accept(symbol);
        if (this.Language.IsWhiteSpace(this.CurrentSymbol))
          symbol = this.CurrentSymbol;
        else if (this.Language.IsNewLine(this.CurrentSymbol))
        {
          this.Accept(this.CurrentSymbol);
          symbol = default (TSymbol);
        }
        this.Tokenizer.Next();
      }
      return symbol;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines whether the token is at the specified identifier.</summary>
    /// <returns>true if the token is at the specified identifier; otherwise, false.</returns>
    /// <param name="allowKeywords">true to allow keywords; otherwise, false.</param>
    protected bool AtIdentifier(bool allowKeywords)
    {
      if ((object) this.CurrentSymbol == null)
        return false;
      if (this.Language.IsIdentifier(this.CurrentSymbol))
        return true;
      return allowKeywords && this.Language.IsKeyword(this.CurrentSymbol);
    }

    internal IEnumerable<TSymbol> ReadWhileLazy(Func<TSymbol, bool> condition)
    {
      while (this.EnsureCurrent() && condition(this.CurrentSymbol))
      {
        yield return this.CurrentSymbol;
        this.NextToken();
      }
    }

    private void Configure(SpanKind? kind, AcceptedCharacters? accepts)
    {
      if (kind.HasValue)
        this.Span.Kind = kind.Value;
      if (!accepts.HasValue)
        return;
      this.Span.EditHandler.AcceptedCharacters = accepts.Value;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Outputs a span before the razor comment.</summary>
    protected virtual void OutputSpanBeforeRazorComment() => throw new InvalidOperationException(RazorResources.Language_Does_Not_Support_RazorComment);

    private void CommentSpanConfig(SpanBuilder span)
    {
      span.CodeGenerator = SpanCodeGenerator.Null;
      span.EditHandler = SpanEditHandler.CreateDefault(new Func<string, IEnumerable<ISymbol>>(this.Language.TokenizeString));
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Displays the razor comment.</summary>
    protected void RazorComment()
    {
      if (!this.Language.KnowsSymbolType(KnownSymbolType.CommentStart) || !this.Language.KnowsSymbolType(KnownSymbolType.CommentStar) || !this.Language.KnowsSymbolType(KnownSymbolType.CommentBody))
        throw new InvalidOperationException(RazorResources.Language_Does_Not_Support_RazorComment);
      this.OutputSpanBeforeRazorComment();
      using (this.PushSpanConfig(new Action<SpanBuilder>(this.CommentSpanConfig)))
      {
        using (this.Context.StartBlock(BlockType.Comment))
        {
          this.Context.CurrentBlock.CodeGenerator = (IBlockCodeGenerator) new RazorCommentCodeGenerator();
          SourceLocation currentLocation = this.CurrentLocation;
          this.Expected(KnownSymbolType.CommentStart);
          this.Output(SpanKind.Transition, AcceptedCharacters.None);
          this.Expected(KnownSymbolType.CommentStar);
          this.Output(SpanKind.MetaCode, AcceptedCharacters.None);
          this.Optional(KnownSymbolType.CommentBody);
          this.AddMarkerSymbolIfNecessary();
          this.Output(SpanKind.Comment);
          bool flag = false;
          if (!this.Optional(KnownSymbolType.CommentStar))
          {
            flag = true;
            this.Context.OnError(currentLocation, RazorResources.ParseError_RazorComment_Not_Terminated);
          }
          else
            this.Output(SpanKind.MetaCode, AcceptedCharacters.None);
          if (!this.Optional(KnownSymbolType.CommentStart))
          {
            if (!flag)
              this.Context.OnError(currentLocation, RazorResources.ParseError_RazorComment_Not_Terminated);
          }
          else
            this.Output(SpanKind.Transition, AcceptedCharacters.None);
        }
      }
      this.Initialize(this.Span);
    }
  }
}
